
#ifndef SX_CAMERA_ARCHETYPE_H
#define SX_CAMERA_ARCHETYPE_H

#include <sxGeometricObject_Archetype.h>
#include <sxCamera.h>

namespace Sx {
namespace Graphics {
namespace Archetypes {
namespace Objects {

/* Renderer Implementation */
using Graphics::Objects::Rendering::RendererImplementation;
using Graphics::Objects::Camera;

/*
 * Archetype implementation of a Camera (See Camera) with a geometric
 * representation.
 */
class Camera_Archetype : public GeometricObject_Archetype<Camera, float, GeometricRepresentation> {
public:
	/* Creates a default camera with the provided renderer */
	Camera_Archetype(const std::shared_ptr<RendererImplementation>& renderer);

	/* 
	 * Creates an orthographic camera with the provided view (locked to the
	 * six axes).
	 */
	Camera_Archetype(Math::View view, const std::shared_ptr<RendererImplementation>& renderer);

	/*
	 * Creates a new camera with a perspective projection for either a first
	 * person perspective or a third person perspective.
	 */
	Camera_Archetype(Math::Perspective perspective, const std::shared_ptr<RendererImplementation>& renderer);

	/*
	 * Creates a new camera with the provided projection and perspective.
	 * If the provided projection is an orthographic view then the default
	 * view of the camera will be provided.
	 */
	Camera_Archetype(Math::Projection projection, Math::Perspective perspective, const std::shared_ptr<RendererImplementation>& renderer);
	virtual ~Camera_Archetype();

	/* Pickable Interface */
	bool pick(const Eigen::Vector3f& pickSegmentStart, const Eigen::Vector3f& pickSegmentEnd, Eigen::Vector3f& intersectionPoint);

	/* Intersectable Interface */
	bool intersect(const Eigen::Vector3f& segment_p0, const Eigen::Vector3f& segment_p1, Eigen::Vector3f& intersectionPoint);

	/* Camera-Geometric Interface Implementation */
	bool setPosition(float x, float y, float z);
	bool setPosition(const Eigen::Vector3f& position);

};

}

}

}

}

#endif
